// STL
#include <utility>                     // std::pair<>, ::make_pair()
#include <vector>                      // std::vector<>

// stats++
#include "statsxx/postprocess/ROC.hpp" // ROC_pt


//
// DESC: Finds the optimal cutoff point on a well-behaved ROC curve, using cost--benefit analysis.
//
// INPUT:
//
//     std::vector<ROC_pt> ROC     :
//     std::vector<double> slopes  :
//
//     double              m       :
//
// OUTPUT:
//
//     bool                success : whether an optimal cutoff was found
//     double              cutoff  : optimal cutoff
//
// NOTE: See the NOTEs in cutoff_CB().
//
inline std::pair<
                 bool,
                 double
                 > cutoff_CB_well_behaved(
                                          const std::vector<ROC_pt> &ROC,
                                          const std::vector<double> &slopes,
                                          // -----
                                          const double               m
                                          )
{
    bool   success;
    double cutoff;

    // CHECK TO SEE IF POINT *CAN* BE FOUND
    if( (slopes.front() < m) || (slopes.back() > m) )
    {
        // NOTE: In either (slope) case, it is not possible to rigorously justify a cutoff.
        //
        // NOTE: ... A conservative cutoff *could* be justified for too low of slope, but this would not be rigorous.

        return std::make_pair(
                              false,
                              double()
                              );
    }

    // FIND THE SURROUNDING POINTS FOR SLOPE m
    int i1;
    int i2;

    for( auto i = 0; i < (slopes.size()-1); ++i )
    {
        // NOTE: For m that equals a point in slopes, this finds the first interval.
        if( (slopes[i] >= m) && (slopes[i+1] <= m) )
        {
            i1 = i;
            i2 = i+1;

            break;
        }
    }

    // INTERPOLATE SLOPE, AND SCORE
    //
    // NOTE: See:
    //
    //     https://en.wikipedia.org/wiki/Linear_interpolation#Linear_interpolation_between_two_known_points
    //
    cutoff = ROC[i1].score + (m - slopes[i1])*(ROC[i2].score - ROC[i1].score)/(slopes[i2] - slopes[i1]);

    // RETURN
    success = true;

    return std::make_pair(
                          success,
                          cutoff
                          );

}
